// acetone, 2024
// I hate copyright of any kind. This is a public domain.
// Original source: https://notabug.org/acetone/samty

#pragma once

#include <string>

namespace Samty {

class Identity
{
public:
    // https://geti2p.net/spec/common-structures Ctrl+F: Certificate

    enum class CertificateType : uint8_t {
        Null = 0,
        HashCash = 1,
        Hidden = 2,
        Signed = 3,
        Multiple = 4,
        Key = 5
    };

    enum class SignatureType : uint16_t {
        DSA_SHA1 = 0,                        // legth 128
        ECDSA_SHA256_P256 = 1,               // legth 64
        ECDSA_SHA384_P384 = 2,               // legth 96
        ECDSA_SHA512_P521 = 3,               // legth 132
        RSA_SHA256_2048 = 4,                 // legth 256
        RSA_SHA384_3072 = 5,                 // legth 384
        RSA_SHA512_4096 = 6,                 // legth 512
        EdDSA_SHA512_Ed25519 = 7,            // legth 32
        EdDSA_SHA512_Ed25519ph = 8,          // legth 32
        GOSTR3410_A_GOSTR3411_256 = 9,       // legth 64
        GOSTR3410_TC26_A_GOSTR3411_512 = 10, // legth 128
        RedDSA_SHA512_Ed25519 = 11           // legth 32
    };
    static constexpr uint16_t MAX_SIGNATURE_TYPE_ID = 11;

    static constexpr uint16_t KEY_LENGTH[]
    {
        128, // DSA_SHA1
        64,  // ECDSA_SHA256_P256
        96,  // ECDSA_SHA384_P384
        132, // ECDSA_SHA512_P521
        256, // RSA_SHA256_2048
        384, // RSA_SHA384_3072
        512, // RSA_SHA512_4096
        32,  // EdDSA_SHA512_Ed25519
        32,  // EdDSA_SHA512_Ed25519ph
        64,  // GOSTR3410_A_GOSTR3411_256
        128, // GOSTR3410_TC26_A_GOSTR3411_512
        32   // RedDSA_SHA512_Ed25519
    };
    static_assert(sizeof(KEY_LENGTH)/sizeof(uint16_t)-1 == MAX_SIGNATURE_TYPE_ID, "Key length struct must == MAX_SIGNATURE_TYPE_ID");

    // Encryption keys used only for routers, not for destinations. So it not processing here.

    Identity();

    bool init(const std::string& base64I2pStyled, bool generateB33 = false);
    bool isOk() const { return not m_destB32.empty(); }

    std::string dest32() const { return m_destB32.empty() ? std::string() : m_destB32 + ".b32.i2p"; }
    std::string dest33() const { return m_destB33.empty() ? std::string() : m_destB33 + ".b32.i2p"; }

    std::string pubBase64() const { return m_pubBase64; }
    std::string fullBase64() const { return m_fullBase64; }

    CertificateType certificateType() const { return m_certificateType; }
    SignatureType signatureType() const { return m_signatureType; }
    std::string errorString() const { return m_errorString; }

private:
    CertificateType m_certificateType = CertificateType::Null;
    SignatureType m_signatureType = SignatureType::DSA_SHA1;

    std::string m_destB32;
    std::string m_destB33;

    std::string m_pubBase64;
    std::string m_fullBase64;

    std::string m_errorString;
};

} // namespace Samty
